package com.chlitina.store.modules.cash.service;

import java.util.Date;
import java.util.List;
import java.util.Map;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.chlitina.store.common.persistence.Page;
import com.chlitina.store.common.service.BaseService;
import com.chlitina.store.modules.base.dao.StoreCareDao;
import com.chlitina.store.modules.base.entity.StoreCare;
import com.chlitina.store.modules.base.entity.StoreSelfCare;
import com.chlitina.store.modules.cash.dao.StoreConsumeDoCareDao;
import com.chlitina.store.modules.cash.entity.StoreConsume;
import com.chlitina.store.modules.cash.entity.StoreConsumeDoCare;
import com.chlitina.store.modules.cash.entity.StoreConsumeNewCard;
import com.chlitina.store.modules.employee.entity.Employee;
import com.chlitina.store.modules.expert.entity.Care;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

/**
 * 散客消费Service
 * 
 * @author Songsong.xu
 * @version 2013-11-07
 */
@Component
@Transactional(readOnly = true)
public class StoreConsumeDoCareService extends BaseService {

	@Autowired
	private StoreConsumeDoCareDao storeConsumeDoCareDao;
	@Autowired
	private StoreCareDao storeCareDao;
	@Autowired
	private StoreConsumeService storeConsumeService;
	
	public StoreConsumeDoCare get(Long id) {
		return storeConsumeDoCareDao.findOne(id);
	}
	
	public Map<Integer, Integer> getByEmployeeSatisfaction(Employee employee, Date start, Date end) {
		List<Long> existConsumeIds = Lists.newArrayList();
		Map<Integer, Integer> map = Maps.newHashMap();
		map.put(StoreConsume.TYPE_SATISFACTIOIN_1, 0);
		map.put(StoreConsume.TYPE_SATISFACTIOIN_2, 0);
		map.put(StoreConsume.TYPE_SATISFACTIOIN_3, 0);
		map.put(StoreConsume.TYPE_SATISFACTIOIN_4, 0);
		map.put(StoreConsume.TYPE_SATISFACTIOIN_5, 0);
		List<StoreConsumeDoCare> byEmployee = getByEmployee(employee, start, end);
		for (StoreConsumeDoCare storeConsumeDoCare : byEmployee) {
			Long id = storeConsumeDoCare.getStoreConsume().getId();
			if(existConsumeIds.contains(id)){
				continue;
			}
			int type = storeConsumeDoCare.getStoreConsume().getSatisfaction();
			if(type != 0) {
				map.put(type, (map.get(type)+1));
			}
		}
		return map;
	}
	
	public Map<Integer, Float> getByEmployeeCost(Employee employee, Date start, Date end) {
		Map<Integer, Float> map = Maps.newHashMap();
		map.put(Care.TYPE_FACE, 0f);
		map.put(Care.TYPE_BODY, 0f);
		map.put(Care.TYPE_DEVICE, 0f);
		List<StoreConsumeDoCare> byEmployee = getByEmployee(employee, start, end);
		for (StoreConsumeDoCare storeConsumeDoCare : byEmployee) {
			if(!storeConsumeService.ifDebtByConsume(storeConsumeDoCare.getStoreConsume().getId())){
				StoreCare storeCare = storeConsumeDoCare.getStoreCare();
				if (storeCare == null) {
					continue;
				}
				int type = 0;
				if(storeCare.getCare_type() == StoreCare.TYPE_SYS) {
					Care care = storeCare.getCare();
					type = care.getType();
				} else {
					StoreSelfCare storeSelfCare = storeCare.getStoreSelfCare();
					type = storeSelfCare.getType();
				}
				float money = map.get(type);
				money += storeConsumeDoCare.getReal_cost();
				map.put(type, money);
			}
		}
		return map;
	}
	
	public float getByEmployeeBonus(Employee employee, Date start, Date end) {
		float money = 0f;
		List<StoreConsumeDoCare> byEmployee = getByEmployee(employee, start, end);
		for (StoreConsumeDoCare storeConsumeDoCare : byEmployee) {
			if(!storeConsumeService.ifDebtByConsume(storeConsumeDoCare.getStoreConsume().getId())){
				money += storeConsumeDoCare.getBonus();
			}
		}
		return money;
	}
	
	public List<StoreConsumeDoCare> getByEmployee(Employee employee, Date start, Date end) {
		DetachedCriteria dc = storeConsumeDoCareDao.createDetachedCriteria();
		dc.add(Restrictions.eq("employee", employee));
		dc.createAlias("storeConsume", "sc");
		if(start != null && end != null) {
			dc.add(Restrictions.between("sc.consume_Time", start, end));
		}
		if(start == null && end != null) {
			dc.add(Restrictions.le("sc.consume_Time", end));
		}
		if(start != null && end == null) {
			dc.add(Restrictions.ge("sc.consume_Time", start));
		}
		dc.add(Restrictions.eq("sc.confirmed", StoreConsume.TYPE_CONFIRMED));
		return storeConsumeDoCareDao.find(dc);
	}
	
	public Page<StoreConsumeDoCare> find(Page<StoreConsumeDoCare> page, StoreConsumeDoCare storeConsumeDoCare) {
		DetachedCriteria dc = storeConsumeDoCareDao.createDetachedCriteria();
		dc.addOrder(Order.desc("id"));
		return storeConsumeDoCareDao.find(page, dc);
	}
	
	@Transactional(readOnly = false)
	public void save(StoreConsumeDoCare storeConsumeDoCare) {
		storeConsumeDoCareDao.save(storeConsumeDoCare);
	}
	
	@Transactional(readOnly = false)
	public void delete(Long id) {
		storeConsumeDoCareDao.delete(id);
	}
}
